package edu.udo.sopra10.chaturaji.events;

import java.util.HashSet;
import java.util.Set;

import edu.udo.sopra10.chaturaji.entities.PieceMove;
import edu.udo.sopra10.chaturaji.entities.Player;
import edu.udo.sopra10.chaturaji.entities.Turn;
import edu.udo.sopra10.chaturaji.entities.coordinates.Position;
import edu.udo.sopra10.chaturaji.entities.transfer.Piece;

/**
 * Move event that is invoked when a move is made on the game board.
 * 
 * @author Patrick Westerhoff
 */
public class MoveEvent extends ChaturajiEvent
{
	private static final long serialVersionUID = 41860564730215863L;
	
	private int turnNumber;
	private byte playerId;
	private byte diceRoll;
	private byte moveScore;
	private int fullScore;
	private Position startPosition;
	private Position endPosition;
	private Piece movedPiece;
	private HashSet<Piece> capturedPieces;
	private HashSet<Piece> promotedPawns;
	
	/**
	 * Constructs a move event based on the {@link PieceMove} entity.
	 * 
	 * @param source the source object.
	 * @param move the move entity this event is based on.
	 */
	public MoveEvent ( Object source, PieceMove move )
	{
		super( source );
		
		Turn turn = move.getTurn();
		Player player = turn.getPlayer();
		
		// copy data from move
		turnNumber = (int) Math.floor( player.getGame().getHistory().indexOf( turn ) / 4 );
		diceRoll = move.getDiceRoll();
		playerId = player.getTurnOrderPosition();
		moveScore = move.getScore();
		fullScore = player.getScore();
		
		startPosition = move.getStartPosition();
		endPosition = move.getEndPosition();
		
		// load moved piece
		movedPiece = Piece.createFromEntity( move.getMovedPiece() );
		
		// load captured pieces
		capturedPieces = new HashSet<Piece>( move.getCapturedPieces().size() );
		for ( edu.udo.sopra10.chaturaji.entities.pieces.Piece entity : move.getCapturedPieces() )
			capturedPieces.add( Piece.createFromEntity( entity ) );
		
		// load promoted pawns
		promotedPawns = new HashSet<Piece>( move.getPromotedPawns().size() );
		for ( edu.udo.sopra10.chaturaji.entities.pieces.Piece entity : move.getPromotedPawns() )
			promotedPawns.add( Piece.createFromEntity( entity ) );
	}
	
	/**
	 * Returns the current turn number.
	 * 
	 * @return the turn number.
	 */
	public int getTurnNumber ()
	{
		return turnNumber;
	}
	
	/**
	 * Returns the id of the current player.
	 * 
	 * @return the player id.
	 */
	public byte getPlayerId ()
	{
		return playerId;
	}
	
	/**
	 * Returns the used dice value.
	 * 
	 * @return the dice roll.
	 */
	public byte getDiceRoll ()
	{
		return diceRoll;
	}
	
	/**
	 * Returns the score of this move.
	 * 
	 * @return the move score.
	 */
	public byte getMoveScore ()
	{
		return moveScore;
	}
	
	/**
	 * Returns the full score of the player after his move.
	 * 
	 * @return the full score.
	 */
	public int getFullScore ()
	{
		return fullScore;
	}
	
	/**
	 * Returns the starting position of this move.
	 * 
	 * @return the start position.
	 */
	public Position getStartPosition ()
	{
		return startPosition;
	}
	
	/**
	 * Returns the ending position of this move.
	 * 
	 * @return the end position.
	 */
	public Position getEndPosition ()
	{
		return endPosition;
	}
	
	/**
	 * Returns the piece that was moved in this move.
	 * 
	 * @return the moved piece.
	 */
	public Piece getMovedPiece ()
	{
		return movedPiece;
	}
	
	/**
	 * Returns a set of all captured pieces.
	 * 
	 * @return the captured pieces.
	 */
	public Set<Piece> getCapturedPieces ()
	{
		return capturedPieces;
	}
	
	/**
	 * Returns a set of all pieces that are the result of a pawn promotion
	 * during this move.
	 * 
	 * @return the promoted pieces.
	 */
	public Set<Piece> getPromotedPawns ()
	{
		return promotedPawns;
	}
}